package com.ljy.my_study.java.juc.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lijunying
 * @date 2021/2/1 11:02
 */
public class TestQueue<V> {

    private int headIndex=0;

    private int tailIndex=0;

    private Object[] array;

    private ReentrantLock lock;

    private Condition notFull;
    private Condition notEmpty;

    public TestQueue(){
        this.array=new Object[10];
        lock=new ReentrantLock();
        notFull=lock.newCondition();
        notEmpty=lock.newCondition();
    }

    public void put(V value){
        try{
            lock.lock();
            if((tailIndex-headIndex)==array.length){
                try {
                    System.out.println(Thread.currentThread().getName()+", notFull.await()");
                    notFull.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            array[tailIndex++]=value;
            notEmpty.signal();
            System.out.println(Thread.currentThread().getName()+", notEmpty.signal()");
        }finally {
            lock.unlock();
        }
    }

    public V take(){
        V result;
        try{
            lock.lock();
            if(tailIndex==headIndex){
                try {
                    System.out.println(Thread.currentThread().getName()+", notEmpty.await()");
                    notEmpty.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            result=(V)array[headIndex++];
            notFull.signal();
            System.out.println(Thread.currentThread().getName()+", notFull.signal()");
        }finally {
            lock.unlock();
        }
        return result;
    }
}
